/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 #include "transmissionv2.h"

 #include "common.h"
 #include "inner_socket.h"
 #include "softbus_bus_center.h"
 #include "softbus_common.h"
 #include "trans_type.h"
 
 #define DATA_SIZE                        128
 #define SESSION_NAME_SUFFIX_MAX_LEN      5
 #define G_SESSION_NAME_LEN               20
 #define G_SESSION_NAME_WITH_SUFFIX_LEN   25
 #define QOS_TYPE_MIN_BW_INDEX            0
 #define QOS_TYPE_MAX_WAIT_TIMEOUT_INDEX  1
 #define QOS_TYPE_MIN_LATENCY_INDEX       2
 #define QOS_TYPE_MAX_BUFFER_INDEX        3
 #define QOS_TYPE_FIRST_PACKAGE_INDEX     4
 #define QOS_TYPE_MAX_IDLE_TIMEOUT_INDEX  5
 #define QOS_TYPE_TRANS_RELIABILITY_INDEX 6
 #define QOS_TYPE_BUTT 7
 #define MAX_QOS_INTERFACE_NUM 12
 #define ENABLE_CUSTOM_QOS_CONFIG 1
 
 static sem_t g_bindSem;
 
 const char *SESSION_NAME_V2 = "IShareAuthSession_";
 static const char *DATA_PATH = "/data";
 static bool bindFlag = false;
 
 static void OnBind(int32_t socket, PeerSocketInfo info)
 {
     printf("\n>>>Onbind socket = %d.", socket);
     printf("\n>>>Onbind peer socket info name= %s, networkId = %s.", info.name, info.networkId);
     printf("\n>>>Onbind peer socket info pkgName= %s, TransDataType = %d.\n", info.pkgName, info.dataType);
     Logf(INFO, "Call On bind success, socket fd = %d\n", socket);
     if (bindFlag) {
         sem_post(&g_bindSem);
     }
     return;
 }
 
 static void OnShutdown(int32_t socket, ShutdownReason reason)
 {
     printf("\n>>>OnShutdown socket = %d, shutdown reason = %d.\n", socket, reason);
     return;
 }
 
 static void OnError(int32_t socket, int32_t errCode)
 {
     printf("\n>>>OnError socket = %d, errCode = %d.\n", socket, errCode);
     Logf(INFO, "Call On bind failed, socket fd = %d\n", socket);
     sem_post(&g_bindSem);
     return;
 }
 
 static void OnBytes(int32_t socket, const void *data, uint32_t dataLen)
 {
     printf("\n>>>OnBytes socket = %d, data = %s.\n", socket, (const char *)data);
     return;
 }
 
 static void OnBytesSent(int32_t socket, uint32_t seq, int32_t errCode)
 {
     printf("\n>>>OnBytesSent socket = %d, seq = %u, errCode = %d", socket, seq, errCode);
     fflush(stdout);
     return;
 }
 
 static void OnMessage(int32_t socket, const void *data, uint32_t dataLen)
 {
     printf("\n>>>OnMessage socket = %d, data = %s.\n", socket, (const char *)data);
     return;
 }
 
 static void OnStream(int32_t socket, const StreamData *data, const StreamData *ext, const StreamFrameInfo *param)
 {
     printf("\n>>>OnStream socket = %d, data = %s, ext = %s.\n", socket, data->buf, ext->buf);
     return;
 }
 
 static const char *UpdateRecvPath(void)
 {
     return DATA_PATH;
 }
 
 static void OnFile(int32_t socket, FileEvent *event)
 {
     printf("\n>>>OnFile socket = %d, FileEventType = %d.", socket, event->type);
     printf("\n>>>OnFile socket = %d, FileCnt = %d.", socket, event->fileCnt);
     int i;
     for (i = 0; i < event->fileCnt; i++) {
         printf("\n>>>OnFile filename id = %d, name = %s", i, event->files[i]);
     }
     printf("\n>>>OnFile bytesProcessed = %" PRId64 ", bytesTotal = %" PRId64 ".", event->bytesProcessed,
         event->bytesTotal);
     event->UpdateRecvPath = UpdateRecvPath;
     return;
 }
 
 static void OnQos(int32_t socket, QoSEvent eventId, const QosTV *qos, uint32_t qosCount)
 {
     printf("\n>>>OnQos socket = %d, QoSEvent = %d.", socket, eventId);
     printf("\n>>>OnQos qos.QosType = %d, qos.Value = %d, qosCount = %d.", qos->qos, qos->value, qosCount);
     return;
 }
 
 static bool GetNetworkIdQos(char *networkId, int32_t networkIdLen)
 {
     int32_t onlineNum = 0;
     NodeBasicInfo *info = NULL;
     int32_t ret = GetAllNodeDeviceInfo(PKG_NAME, &info, &onlineNum);
     if (ret != 0) {
         printf("GetAllNodeDeviceInfo fail, ret = %d.\n", ret);
         return false;
     }
     if (onlineNum == 0) {
         GetInputString("Please input network Id:", networkId, networkIdLen);
     } else if (onlineNum == 1) {
         ret = strcpy_s(networkId, networkIdLen, info[0].networkId);
         if (ret != EOK) {
             FreeNodeInfo(info);
             printf("strcpy networkId fail %d\n", ret);
             return false;
         }
         printf(">>>DeviceNetworkId: %s\n", networkId);
     } else {
         for (int i = 0; i < onlineNum; i++) {
             printf(">>>DeviceName:%s DeviceNetworkId: %s\n", info[i].deviceName, info[i].networkId);
         }
         GetInputString("Please input network Id refer to the above:", networkId, networkIdLen);
     }
     FreeNodeInfo(info);
     return true;
 }
 
 void T_Socket(void)
 {
     printf("\n>>>Choose use socket function\n");
     char networkId[NETWORK_ID_BUF_LEN];
     if (!GetNetworkIdQos(networkId, NETWORK_ID_BUF_LEN)) {
         return;
     }
     char sessionNameSuffix[SESSION_NAME_SUFFIX_MAX_LEN];
     GetInputString("Please input session name suffix (max 5 chars):", sessionNameSuffix, SESSION_NAME_SUFFIX_MAX_LEN);
     char sessionName[G_SESSION_NAME_WITH_SUFFIX_LEN] = { 0 };
     int32_t ret = strcat_s(sessionName, G_SESSION_NAME_WITH_SUFFIX_LEN, SESSION_NAME_V2);
     if (ret != EOK) {
         printf("copy data failed, ret = %d\n", ret);
         return;
     }
     ret = strcat_s(sessionName, G_SESSION_NAME_WITH_SUFFIX_LEN, sessionNameSuffix);
     if (ret != EOK) {
         printf("copy data failed, ret = %d\n", ret);
         return;
     }
     SocketInfo info;
     info.pkgName = PKG_NAME;
     info.name = sessionName;
     info.peerName = sessionName;
     info.peerNetworkId = networkId;
     info.dataType =
         GetInputNumber("Please input socket data type(1 - TYPE_MESSAGE, 2 - TYPE_BYTES, 3 - TYPE_FILE, 4 - "
                        "TYPE_RAW_STREAM, 5 - TYPE_VIDEO_STREAM, 6 - TYPE_AUDIO_STREAM, 7 - TYPE_SLICE_STREAM):");
     int32_t socket = Socket(info);
     if (socket > 0) {
         printf("Socket success, socket fd = %d\n", socket);
     } else {
         printf("Socket failed, errCode = %d\n", socket);
     }
 }
 
 static ISocketListener g_listener = {
     .OnBind = OnBind,
     .OnError = OnError,
     .OnShutdown = OnShutdown,
     .OnMessage = OnMessage,
     .OnStream = OnStream,
     .OnFile = OnFile,
     .OnQos = OnQos,
     .OnBytes = OnBytes,
     .OnBytesSent = OnBytesSent,
 };
 
 static void GetQosParam(int32_t *values, int32_t *isCustomQosInfo)
 {
     *isCustomQosInfo =
         GetInputNumber("Use custom qos info ? 0 - default (QOS_TYPE_MIN_BW=10*1024*1024, "
                        "QOS_TYPE_MAX_WAIT_TIMEOUT=4000, QOS_TYPE_MIN_LATENCY=2000), 1 - custom :");
     if (*isCustomQosInfo == ENABLE_CUSTOM_QOS_CONFIG) {
         values[QOS_TYPE_MIN_BW_INDEX] = GetInputNumber("Please input QOS_TYPE_MIN_BW value:");
         values[QOS_TYPE_MAX_WAIT_TIMEOUT_INDEX] = GetInputNumber("Please input QOS_TYPE_MAX_WAIT_TIMEOUT value:");
         values[QOS_TYPE_MIN_LATENCY_INDEX] = GetInputNumber("Please input QOS_TYPE_MIN_LATENCY value:");
         values[QOS_TYPE_MAX_BUFFER_INDEX] = GetInputNumber("Please input QOS_TYPE_MAX_BUFFER value:");
         values[QOS_TYPE_FIRST_PACKAGE_INDEX] = GetInputNumber("Please input QOS_TYPE_FIRST_PACKAGE value:");
         values[QOS_TYPE_MAX_IDLE_TIMEOUT_INDEX] = GetInputNumber("Please input QOS_TYPE_MAX_IDLE_TIMEOUT value:");
         values[QOS_TYPE_TRANS_RELIABILITY_INDEX] = GetInputNumber("Please input QOS_TYPE_TRANS_RELIABILITY value:");
     }
 }
 
 void T_Bind(void)
 {
     printf("\n>>>Choose use bind function\n");
     int32_t socketfd = GetInputNumber("Please input socket fd id:");
     int32_t isCustomQosInfo = 0;
     int32_t qosCount = 0;
     int32_t values[QOS_TYPE_BUTT];
     GetQosParam(values, &isCustomQosInfo);
     QosTV qosInfoDefault[] = {
         { .qos = QOS_TYPE_MIN_BW,           .value = 10 * 1024 * 1024},
         { .qos = QOS_TYPE_MAX_WAIT_TIMEOUT, .value = 4000            },
         { .qos = QOS_TYPE_MIN_LATENCY,      .value = 2000            },
     };
     QosTV qosInfoCustorm[] = {
         { .qos = QOS_TYPE_MIN_BW,            .value = values[QOS_TYPE_MIN_BW_INDEX]           },
         { .qos = QOS_TYPE_MAX_WAIT_TIMEOUT,  .value = values[QOS_TYPE_MAX_WAIT_TIMEOUT_INDEX] },
         { .qos = QOS_TYPE_MIN_LATENCY,       .value = values[QOS_TYPE_MIN_LATENCY_INDEX]      },
         { .qos = QOS_TYPE_MAX_BUFFER,        .value = values[QOS_TYPE_MAX_BUFFER_INDEX]       },
         { .qos = QOS_TYPE_FIRST_PACKAGE,     .value = values[QOS_TYPE_FIRST_PACKAGE_INDEX]    },
         { .qos = QOS_TYPE_MAX_IDLE_TIMEOUT,  .value = values[QOS_TYPE_MAX_IDLE_TIMEOUT_INDEX] },
         { .qos = QOS_TYPE_TRANS_RELIABILITY, .value = values[QOS_TYPE_TRANS_RELIABILITY_INDEX]},
     };
     QosTV *qosInfo = NULL;
     if (isCustomQosInfo) {
         qosInfo = &qosInfoCustorm[0];
         qosCount = sizeof(qosInfoCustorm) / sizeof(qosInfoCustorm[0]);
     } else {
         qosInfo = &qosInfoDefault[0];
         qosCount = sizeof(qosInfoDefault) / sizeof(qosInfoDefault[0]);
     }
     sem_init(&g_bindSem, 0, 0);
     Logf(INFO, "Begin bind func, socket fd = %d\n", socketfd);
     int32_t ret = Bind(socketfd, qosInfo, qosCount, &g_listener);
     if (ret < 0) {
         printf("Bind failed, socket fd = %d\n", socketfd);
         sem_destroy(&g_bindSem);
         return;
     }
     Logf(INFO, "Bind func success, socket fd = %d\n", socketfd);
     printf("Bind finish, socket fd = %d\n", socketfd);
     sem_destroy(&g_bindSem);
 }
 
 void T_BindAsync(void)
 {
     printf("\n>>>Choose use async bind function\n");
     int32_t socketfd = GetInputNumber("Please input socket fd id:");
     int32_t isCustomQosInfo = 0;
     int32_t qosCount = 0;
     int32_t values[QOS_TYPE_BUTT];
     GetQosParam(values, &isCustomQosInfo);
     QosTV qosInfoDefault[] = {
         { .qos = QOS_TYPE_MIN_BW,           .value = 10 * 1024 * 1024},
         { .qos = QOS_TYPE_MAX_WAIT_TIMEOUT, .value = 4000            },
         { .qos = QOS_TYPE_MIN_LATENCY,      .value = 2000            },
     };
     QosTV qosInfoCustorm[] = {
         { .qos = QOS_TYPE_MIN_BW,            .value = values[QOS_TYPE_MIN_BW_INDEX]           },
         { .qos = QOS_TYPE_MAX_WAIT_TIMEOUT,  .value = values[QOS_TYPE_MAX_WAIT_TIMEOUT_INDEX] },
         { .qos = QOS_TYPE_MIN_LATENCY,       .value = values[QOS_TYPE_MIN_LATENCY_INDEX]      },
         { .qos = QOS_TYPE_MAX_BUFFER,        .value = values[QOS_TYPE_MAX_BUFFER_INDEX]       },
         { .qos = QOS_TYPE_FIRST_PACKAGE,     .value = values[QOS_TYPE_FIRST_PACKAGE_INDEX]    },
         { .qos = QOS_TYPE_MAX_IDLE_TIMEOUT,  .value = values[QOS_TYPE_MAX_IDLE_TIMEOUT_INDEX] },
         { .qos = QOS_TYPE_TRANS_RELIABILITY, .value = values[QOS_TYPE_TRANS_RELIABILITY_INDEX]},
     };
     QosTV *qosInfo = NULL;
     if (isCustomQosInfo) {
         qosInfo = &qosInfoCustorm[0];
         qosCount = sizeof(qosInfoCustorm) / sizeof(qosInfoCustorm[0]);
     } else {
         qosInfo = &qosInfoDefault[0];
         qosCount = sizeof(qosInfoDefault) / sizeof(qosInfoDefault[0]);
     }
     bindFlag = true;
     sem_init(&g_bindSem, 0, 0);
     Logf(INFO, "Begin async bind func, socket fd = %d\n", socketfd);
     int32_t ret = BindAsync(socketfd, qosInfo, qosCount, &g_listener);
     if (ret < 0) {
         printf("Async bind failed, socket fd = %d\n", socketfd);
         sem_destroy(&g_bindSem);
         return;
     }
     Logf(INFO, "Begin async bind finish, begin wait call back, socket fd = %d\n", socketfd);
     sem_wait(&g_bindSem);
     printf("Async bind finish, socket fd = %d\n", socketfd);
     sem_destroy(&g_bindSem);
     bindFlag = false;
 }
 
 void T_Listen(void)
 {
     printf("\n>>>Choose use listen function\n");
     int32_t socketfd = GetInputNumber("Please input socket fd id:");
     int32_t isCustomQosInfo = 0;
     int32_t qosCount = 0;
     int32_t values[QOS_TYPE_BUTT];
     GetQosParam(values, &isCustomQosInfo);
     QosTV qosInfoDefault[] = {
         { .qos = QOS_TYPE_MIN_BW,           .value = 10 * 1024 * 1024},
         { .qos = QOS_TYPE_MAX_WAIT_TIMEOUT, .value = 4000            },
         { .qos = QOS_TYPE_MIN_LATENCY,      .value = 2000            },
     };
     QosTV qosInfoCustorm[] = {
         { .qos = QOS_TYPE_MIN_BW,            .value = values[QOS_TYPE_MIN_BW_INDEX]           },
         { .qos = QOS_TYPE_MAX_WAIT_TIMEOUT,  .value = values[QOS_TYPE_MAX_WAIT_TIMEOUT_INDEX] },
         { .qos = QOS_TYPE_MIN_LATENCY,       .value = values[QOS_TYPE_MIN_LATENCY_INDEX]      },
         { .qos = QOS_TYPE_MAX_BUFFER,        .value = values[QOS_TYPE_MAX_BUFFER_INDEX]       },
         { .qos = QOS_TYPE_FIRST_PACKAGE,     .value = values[QOS_TYPE_FIRST_PACKAGE_INDEX]    },
         { .qos = QOS_TYPE_MAX_IDLE_TIMEOUT,  .value = values[QOS_TYPE_MAX_IDLE_TIMEOUT_INDEX] },
         { .qos = QOS_TYPE_TRANS_RELIABILITY, .value = values[QOS_TYPE_TRANS_RELIABILITY_INDEX]},
     };
     QosTV *qosInfo = NULL;
     if (isCustomQosInfo) {
         qosInfo = &qosInfoCustorm[0];
         qosCount = sizeof(qosInfoCustorm) / sizeof(qosInfoCustorm[0]);
     } else {
         qosInfo = &qosInfoDefault[0];
         qosCount = sizeof(qosInfoDefault) / sizeof(qosInfoDefault[0]);
     }
 
     Logf(INFO, "Begin listen func, socket fd = %d\n", socketfd);
     int32_t ret = Listen(socketfd, qosInfo, qosCount, &g_listener);
     if (ret < 0) {
         printf("listen failed, socket fd = %d\n", socketfd);
         return;
     }
     printf("listen finish, socket fd = %d\n", socketfd);
 }
 
 void T_Shutdown(void)
 {
     int32_t socket;
     socket = GetInputNumber("Please input socket Id:");
     Shutdown(socket);
     printf("Shutdown finish\n");
 }
 
 void T_SendMessageQos(void)
 {
     int32_t socket;
     char data[DATA_SIZE];
     socket = GetInputNumber("Please input socket Id:");
     GetInputString("Please input data to SendMessage:", data, DATA_SIZE);
     int32_t ret = SendMessage(socket, data, strlen(data) + 1);
     if (ret != 0) {
         printf("SendMessage failed, ret = %d\n", ret);
     } else {
         printf("SendMessage success\n");
     }
 }
 
 void T_SendBytesQos(void)
 {
     int32_t socket;
     char data[DATA_SIZE];
     socket = GetInputNumber("Please input socket Id:");
     GetInputString("Please input data to SendBytes:", data, DATA_SIZE);
     int32_t ret = SendBytes(socket, data, strlen(data) + 1);
     if (ret != 0) {
         printf("SendBytes failed, ret = %d\n", ret);
     } else {
         printf("SendBytes success\n");
     }
 }
 
 void T_SendBytesAsyncQos(void)
 {
     int32_t socket;
     char data[DATA_SIZE];
     int32_t dataSeq;
     socket = GetInputNumber("Please input socket Id:");
     dataSeq = GetInputNumber("Please input dataSeq:");
     GetInputString("Please input data to SendBytesAsync:", data, DATA_SIZE);
     int32_t ret = SendBytesAsync(socket, dataSeq, data, strlen(data) + 1);
     if (ret != 0) {
         printf("SendBytesAsync failed, ret = %d\n", ret);
     } else {
         printf("SendBytesAsync success\n");
     }
 }
 
 void T_SendStreamQos(void)
 {
     int32_t socket;
     char data[DATA_SIZE];
     StreamData d1 = { 0 };
     socket = GetInputNumber("Please input socket Id:");
     GetInputString("Please input data to SendStream:", data, DATA_SIZE);
     d1.buf = data;
     d1.bufLen = strlen(data) + 1;
     StreamData d2 = { 0 };
     StreamFrameInfo tmpf = { 0 };
 
     int32_t ret = SendStream(socket, &d1, &d2, &tmpf);
     if (ret != 0) {
         printf("SendStream failed, ret = %d\n", ret);
     } else {
         printf("SendStream success\n");
     }
 }
 
 void T_SendFileQos(void)
 {
     int32_t socket;
     const char *sfileList[1] = { NULL };
     char filePath[DATA_SIZE] = { 0 };
     socket = GetInputNumber("Please input session Id:");
     GetInputString("Please input file path to SendFile:", filePath, DATA_SIZE);
     sfileList[0] = filePath;
     int32_t ret = SendFile(socket, sfileList, NULL, 1);
     if (ret != 0) {
         printf("SendFile failed, ret = %d\n", ret);
     } else {
         printf("SendFile success\n");
     }
 }
 
 void T_GetSocketOpt(void)
 {
     int32_t socket;
     int32_t level;
     int32_t optType;
     void *optValue;
     int32_t optValueSize;
     bool supportTlv = false;
     socket = GetInputNumber("Please input session Id:");
     level = GetInputNumber("Please input level type(0 - OPT_LEVEL_KERNEL, 1 - OPT_LEVEL_SOFTBUS, 2 - OPT_LEVEL_BUTT:");
     optType = GetInputNumber("Please input optType(0 - OPT_TYPE_MAX_BUFFER, 1 - OPT_TYPE_FIRST_PACKAGE,"
         "2 - OPT_TYPE_MAX_IDLE_TIMEOUT, 3 - OPT_TYPE_GET_SUPPORT_ACK, 4 - OPT_TYPE_NEED_ACK, 5 - OPT_TYPE_END):");
     switch (optType) {
         case OPT_TYPE_SUPPORT_ACK:
             optValue = &supportTlv;
             optValueSize = 1;
             break;
         case OPT_TYPE_MAX_BUFFER:
         case OPT_TYPE_FIRST_PACKAGE:
         case OPT_TYPE_MAX_IDLE_TIMEOUT:
         case OPT_TYPE_NEED_ACK:
             optValue = &socket;
             optValueSize = sizeof(optValue);
             break;
         default:
             printf("invalid optType, optType = %d\n", optType);
             optValue = &socket;
             optValueSize = sizeof(optValue);
             break;
     }
     int32_t ret = GetSocketOpt(socket, level, optType, optValue, &optValueSize);
     if (ret == 0) {
         printf("GetSocketOpt success, ret = %d\n", ret);
         if (optType == OPT_TYPE_SUPPORT_ACK) {
             printf("GetSocketOpt supportTlv optValue = %d\n", *(bool*)optValue);
         }
     } else {
         printf("GetSocketOpt failed, ret = %d\n", ret);
     }
 }
 
 void T_SetSocketOpt(void)
 {
     int32_t socket;
     int32_t level;
     int32_t optType;
     void *optValue;
     int32_t optValueSize;
     int32_t value;
     socket = GetInputNumber("Please input session Id:");
     level = GetInputNumber("Please input level type(0 - OPT_LEVEL_KERNEL, 1 - OPT_LEVEL_SOFTBUS, 2 - OPT_LEVEL_BUTT:");
     optType = GetInputNumber("Please input optType(0 - OPT_TYPE_MAX_BUFFER, 1 - OPT_TYPE_FIRST_PACKAGE,"
         "2 - OPT_TYPE_MAX_IDLE_TIMEOUT, 3 - OPT_TYPE_GET_SUPPORT_ACK, 4 - OPT_TYPE_NEED_ACK, 5 - OPT_TYPE_END):");
     switch (optType) {
         case OPT_TYPE_NEED_ACK:
             value = GetInputNumber("Please input set needAck value(0 - false, 1 - true):");
             bool needAck = (bool)value;
             optValue = &needAck;
             optValueSize = 1;
             break;
         case OPT_TYPE_MAX_BUFFER:
         case OPT_TYPE_FIRST_PACKAGE:
         case OPT_TYPE_MAX_IDLE_TIMEOUT:
         case OPT_TYPE_SUPPORT_ACK:
             optValue = &socket;
             optValueSize = sizeof(optValue);
             break;
         default:
             printf("invalid optType, optType = %d\n", optType);
             optValue = &socket;
             optValueSize = sizeof(optValue);
             break;
     }
     int32_t ret = SetSocketOpt(socket, level, optType, optValue, optValueSize);
     if (ret == 0) {
         printf("SetSocketOpt success, ret = %d\n", ret);
     } else {
         printf("SetSocketOpt failed, ret = %d\n", ret);
     }
 }
 
 void T_EvaluateQos(void)
 {
     char networkId[NETWORK_ID_BUF_LEN];
     GetInputString("Please input peeer network Id:", networkId, NETWORK_ID_BUF_LEN);
     int32_t dataType =
         GetInputNumber("Please input socket data type(1 - TYPE_MESSAGE, 2 - TYPE_BYTES, 3 - TYPE_FILE, 4 - "
                        "TYPE_RAW_STREAM, 5 - TYPE_VIDEO_STREAM, 6 - TYPE_AUDIO_STREAM, 7 - TYPE_SLICE_STREAM):");
     int32_t isCustomQosInfo = 0;
     int32_t qosCount = 0;
     int32_t values[QOS_TYPE_BUTT];
     GetQosParam(values, &isCustomQosInfo);
     QosTV qosInfoDefault[] = {
         { .qos = QOS_TYPE_MIN_BW,           .value = 10 * 1024 * 1024},
         { .qos = QOS_TYPE_MAX_WAIT_TIMEOUT, .value = 4000            },
         { .qos = QOS_TYPE_MIN_LATENCY,      .value = 2000            },
     };
     QosTV qosInfoCustorm[] = {
         { .qos = QOS_TYPE_MIN_BW,            .value = values[QOS_TYPE_MIN_BW_INDEX]           },
         { .qos = QOS_TYPE_MAX_WAIT_TIMEOUT,  .value = values[QOS_TYPE_MAX_WAIT_TIMEOUT_INDEX] },
         { .qos = QOS_TYPE_MIN_LATENCY,       .value = values[QOS_TYPE_MIN_LATENCY_INDEX]      },
         { .qos = QOS_TYPE_MAX_BUFFER,        .value = values[QOS_TYPE_MAX_BUFFER_INDEX]       },
         { .qos = QOS_TYPE_FIRST_PACKAGE,     .value = values[QOS_TYPE_FIRST_PACKAGE_INDEX]    },
         { .qos = QOS_TYPE_MAX_IDLE_TIMEOUT,  .value = values[QOS_TYPE_MAX_IDLE_TIMEOUT_INDEX] },
         { .qos = QOS_TYPE_TRANS_RELIABILITY, .value = values[QOS_TYPE_TRANS_RELIABILITY_INDEX]},
     };
     QosTV *qosInfo = NULL;
     if (isCustomQosInfo) {
         qosInfo = &qosInfoCustorm[0];
         qosCount = sizeof(qosInfoCustorm) / sizeof(qosInfoCustorm[0]);
     } else {
         qosInfo = &qosInfoDefault[0];
         qosCount = sizeof(qosInfoDefault) / sizeof(qosInfoDefault[0]);
     }
     Logf(INFO, "Begin evaluateQos func.\n");
     int32_t ret = EvaluateQos(networkId, dataType, qosInfo, qosCount);
     if (ret < 0) {
         printf("evaluateQos failed.\n");
         return;
     }
     printf("evaluateQos finish.\n");
 }
 
 
 static QosInterfacesList g_qosInterfaceList[] = {
     {CREATE_SOCKET, T_Socket},
     {BIND_SOCKET, T_Bind},
     {BIND_ASYNC_SOCKET, T_BindAsync},
     {LISTEN_SOCKET, T_Listen},
     {SHUTDOWN_SOCKET, T_Shutdown},
     {EVALUATE_QOS, T_EvaluateQos},
     {SEND_MESSAGE_QOS, T_SendMessageQos},
     {SEND_BYTES_QOS, T_SendBytesQos},
     {SEND_BYTES_ASYNC_QOS, T_SendBytesAsyncQos},
     {SEND_STREAM_QOS, T_SendStreamQos},
     {SEND_FILE_QOS, T_SendFileQos},
     {GET_SOCKET_OPT, T_GetSocketOpt},
     {SET_SOCKET_OPT, T_SetSocketOpt},
 };
 
 void T_TransQosInterfaceTest(void)
 {
     int32_t choice = 0;
     while (true) {
         choice = GetInputNumber("The trans qos interfaces test functions show as below:\n"
             "-----------------------------------------\n"
             "|   0 - CreateSocket                    |\n"
             "|   1 - BindSocket                      |\n"
             "|   2 - BindAsyncSocket                 |\n"
             "|   3 - ListenSocket                    |\n"
             "|   4 - ShutdownSocket                  |\n"
             "|   5 - EvaluateQos                     |\n"
             "|   6 - SendMessageQos                  |\n"
             "|   7 - SendBytesQos                    |\n"
             "|   8 - SendBytesAsyncQos               |\n"
             "|   9 - SendStreamQos                   |\n"
             "|   10 - SendFileQos                    |\n"
             "|   11 - GetSocketOpt                   |\n"
             "|   12 - SetSocketOpt                   |\n"
             "-----------------------------------------\n"
             "Please input num: ");
         if (choice >= 0 && choice <= MAX_QOS_INTERFACE_NUM) {
             break;
         }
         Logf(INFO, ">>>The input num is invalid, please input again!!!");
     }
     if (g_qosInterfaceList[choice].transFunc != NULL) {
         g_qosInterfaceList[choice].transFunc();
     } else {
         Logf(WARN, "Not support yet\n");
     }
 }